package org.vsg.stock.basic.service.business;

import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Vector;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.vsg.common.biz.exception.ServiceException;
import org.vsg.stock.basic.domain.BalanceLine;
import org.vsg.stock.basic.domain.BalanceLineCharacter;
import org.vsg.stock.basic.domain.BalanceLineKeyPoint;
import org.vsg.stock.basic.persistence.mybatis.proxy.BalanceLineProxy;
import org.vsg.stock.bulk.io.PostgreSQLDataImport;

/**
 * 
 * @author Bill Vison
 *
 */
public class StockBalancLineControlerBO {
	
	private Queue<BalanceLine> lineQueue = new LinkedList<BalanceLine>();
	
	private static final Logger logger = LoggerFactory.getLogger(StockBalancLineControlerBO.class);	
	
	private boolean asynchronous;
	
	static private DateFormat df = new SimpleDateFormat("yyyy-MM-dd");	
	
	@Autowired
	private PostgreSQLDataImport postgreSQLDataImport;	
	
	public void setAsynchronous(boolean asynchronous) {
		this.asynchronous = asynchronous;
	}
	
	/**
	 * defined lines require to endure
	 */
	public void pushLinesToQuery(List<BalanceLine> linesNeedAdd) {
		for (BalanceLine balLine : linesNeedAdd) {
			lineQueue.offer( balLine );
		}
	}
	
	public void endure() {
		
		
		List<BalanceLine> tmpLines = new Vector<BalanceLine>();
		List<BalanceLineKeyPoint> tmpPoints = new Vector<BalanceLineKeyPoint>();
		List<BalanceLineCharacter> tmpCharacter = new Vector<BalanceLineCharacter>();
			
		List<String> mappingList = new Vector<String>();
		
		BalanceLine line = lineQueue.poll();
		
		do {
			
			if (line == null) {
				continue;
			}
			
			tmpLines.add( line );
			tmpPoints.addAll( line.getKeyPoints() );

			if ( line.getCharasters() != null) {
				tmpCharacter.addAll( line.getCharasters() );
			}
			
			for (BalanceLineKeyPoint keyPoint : line.getKeyPoints()) {
				String keyStr = line.getLineId()+","+keyPoint.getPointId();
				if (!mappingList.contains(keyStr)) {
					mappingList.add(keyStr);
				}
			}

		} while ( (line = lineQueue.poll()) != null );


		
		// --- defined allline ---
		try{
			
			postgreSQLDataImport.connect();
						
			endureLines(tmpLines);
			
			endurePoints(tmpPoints);
			
			endureCharacter(tmpCharacter);
			
			endureMap( mappingList);

			
		} finally {
			postgreSQLDataImport.disconnect();					
		}
		
	}
	
	/**
	 * add the lines 
	 * @param allLines
	 */
	private void endureLines(List<BalanceLine> allLines) {
		
		StringBuffer dataOutput = new StringBuffer();
		
		for (Iterator<BalanceLine> lineIter = allLines.iterator() ; lineIter.hasNext();) {
			BalanceLineProxy line = (BalanceLineProxy)lineIter.next();
			
			if (line.isExisted()) {
				continue;
			}

			dataOutput.append( line.getLineId() ).append(",");
			dataOutput.append( line.getStockCode() ).append(",");
			dataOutput.append( line.getForm() );
			dataOutput.append("\n");		
		
		}

		
		
		// --- import new data ----
		InputStream is  = null;
		
		String[] fields = {
				"line_id",
				"stock_code" ,
				"form"};
		
		try {

			is = IOUtils.toInputStream(dataOutput.toString());
			
			// --- import data ----
			postgreSQLDataImport.importData("balance_line", is, fields);
			
			if ( logger.isDebugEnabled() ) {
				String stkCode = allLines.get(0).getStockCode();
				logger.debug("Save  ["+stkCode+"] Basic Line ");
			}
			
		} catch (ServiceException e) {

			e.printStackTrace();
		} catch (IOException e) {

			e.printStackTrace();
		}
		
		
	
	}
	
	private void endurePoints(List<BalanceLineKeyPoint> allPoints) {
		StringBuffer dataOutput = new StringBuffer();
		for (BalanceLineKeyPoint linePoint : allPoints) {
			dataOutput.append( linePoint.getPointId() ).append(",");
			dataOutput.append( linePoint.getStockCode() ).append(",");
			dataOutput.append( df.format( linePoint.getRefDate() )).append(",");
			dataOutput.append( linePoint.getPrice() ).append(",");
			dataOutput.append( linePoint.getPriceType() ).append(",");
			dataOutput.append( linePoint.getIntegerFlag() ).append(",");
			dataOutput.append( linePoint.getSubstanceFlag() );
			
			dataOutput.append("\n");
		}
		// --- import new data ----
		InputStream is  = null;

		String[] fields = {
				"point_id",
				"stock_code",
				"ref_date" ,
				"price",
				"price_type",
				"integer_flag",
				"substance_flag"
		};
		
		try {

			is = IOUtils.toInputStream(dataOutput.toString());
			
			// --- import data ----
			postgreSQLDataImport.importData("balance_line_keypoint", is, fields);

		} catch (ServiceException e) {

			e.printStackTrace();
		} catch (IOException e) {

			e.printStackTrace();
		}

	}

	private void endureMap(List<String> allMaps) {
		
		StringBuffer dataOutput = new StringBuffer();
		for (String mapStr : allMaps) {
			dataOutput.append( mapStr);
			dataOutput.append("\n");
		}
		
		// --- import new data ----
		InputStream is  = null;

		String[] fields = {
				"line_id",
				"point_id" 
		};
		
		try {

			is = IOUtils.toInputStream(dataOutput.toString());
			
			// --- import data ----
			postgreSQLDataImport.importData("balance_line_keypoint_m", is, fields);

		} catch (ServiceException e) {

			e.printStackTrace();
		} catch (IOException e) {

			e.printStackTrace();
		}		
	}

	private void endureCharacter(List<BalanceLineCharacter> allCharacters) {
		StringBuffer dataOutput = new StringBuffer();
		for (BalanceLineCharacter chara : allCharacters) {
			dataOutput.append( chara.getId().getLineId()  ).append(",");
			dataOutput.append(  chara.getId().getCode() );
			dataOutput.append("\n");
		}
		
		// --- import new data ----
		InputStream is  = null;

		String[] fields = {
				"line_id",
				"code"
		};
		
		try {

			is = IOUtils.toInputStream(dataOutput.toString());
			
			// --- import data ----
			postgreSQLDataImport.importData("balance_line_character", is, fields);

		} catch (ServiceException e) {

			e.printStackTrace();
		} catch (IOException e) {

			e.printStackTrace();
		}
		
	}
	
	
	public enum NoticeResult {
		SUCCESS, FAIL
	}	
	
	/**
	 * mark the notice result 
	 * @author Bill Vison
	 *
	 */
	public class Notice {
		
		public NoticeResult receivedResult() {
			return NoticeResult.SUCCESS;
		}
		
	}

}
